package com.mlog.njyjy.ndop.share.kafka.oauth.handler;

import com.mlog.njyjy.ndop.share.kafka.oauth.OauthBearerTokenJwt;
import org.apache.kafka.common.KafkaException;
import org.apache.kafka.common.security.oauthbearer.OAuthBearerTokenCallback;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.AppConfigurationEntry;
import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * .
 * </p>
 *
 * @author <a href="mailto:yingxiufeng@mlogcn.com">alex</a>
 * @version v1.0, 2020/7/13
 */
public class OauthAuthenticateLoginCallbackHandler extends OauthAuthenticateBaseCallbackHandler {

    private final Logger log = LoggerFactory.getLogger(OauthAuthenticateLoginCallbackHandler.class);

    @Override
    public void configure(Map<String, ?> map, String saslMechanism, List<AppConfigurationEntry> jaasConfigEntries) {
        super.configure(map, saslMechanism, jaasConfigEntries);
    }

    private boolean isConfigured() {
        return this.configured;
    }

    @Override
    public void close() {
    }

    @Override
    public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
        if (!isConfigured()) {
            throw new IllegalStateException("Callback handler not configured");
        }
        for (Callback callback : callbacks) {
            if (callback instanceof OAuthBearerTokenCallback) {
                try {
                    handleCallback((OAuthBearerTokenCallback) callback);
                } catch (KafkaException e) {
                    throw new IOException(e.getMessage(), e);
                }
            } else {
                throw new UnsupportedCallbackException(callback);
            }
        }
    }

    private void handleCallback(OAuthBearerTokenCallback callback) {
        if (callback.token() != null) {
            throw new IllegalArgumentException("Callback had a token already");
        }

        log.info("Try to acquire token!");
        OauthBearerTokenJwt token = oauthRequest.login(null);
        log.info("Retrieved token..");
        if (token == null) {
            throw new IllegalArgumentException("Null token returned from server");
        }
        callback.token(token);
    }
}
